interface _CO_ {
    /**
     * 设置属性
     * @param obj 对象
     * @param key 属性键
     * @param value 属性值
     * @param description 属性描述对象
     */
    setProperty(obj: object, key: PropertyKey, value: any, description?: PropertyDescriptor): void;
}
{
    const setProperty = U.F.overloading('Ojbect-setProperty',
        {
            types: [Etype.obj, U.F.argType.propertyKey, U.F.argType.any, Etype.obj],
            fn: function (obj: object, key: PropertyKey, value: any, description: any) {
                const writable = U.defaultValue(Etype.boolean, description.writable, true);
                const enumerable = U.defaultValue(Etype.boolean, description.enumerable, true);
                const configurable = U.defaultValue(Etype.boolean, description.configurable, true);

                const descriptionX: any = {
                    value: value,
                    writable: writable,
                    enumerable: enumerable,
                    configurable: configurable,
                };

                if (writable && enumerable && configurable) {
                    descriptionX.get = U.defaultValue(Etype.function, description.get, undefined);
                    descriptionX.set = U.defaultValue(Etype.function, description.set, undefined);
                }

                Object.defineProperty(obj, key, descriptionX);
            }
        },
        {
            types: [Etype.obj, U.F.argType.propertyKey, U.F.argType.any, U.F.argType.optional(Etype.undefined, Etype.null)],
            fn: function (obj: object, key: PropertyKey, value: any) {
                (obj as any)[key] = value;
            }
        },
    );

    Object.defineProperty(_CO_.prototype, 'setProperty', {
        writable: false,
        configurable: false,
        enumerable: false,
        value: setProperty
    });
}
